﻿using GalaSoft.MvvmLight.Messaging;
using ICSharpCode.AvalonEdit;
using JiveMessenger.AvalonEdit;
using JiveMessenger.ViewModels;
using JiveMessenger.Models;
using NLog;
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Linq;
using System.Windows.Media.Animation;
using System.Windows.Media;
using System.Windows.Data;

namespace JiveMessenger.CustomControls
{
    /// <summary>
    /// Interaction logic for GroupChatControl.xaml
    /// </summary>
    public partial class GroupChatControl : UserControl
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
        public GroupChatControl()
        {
            InitializeComponent();

            if (DesignerProperties.GetIsInDesignMode(this))
            {
                return;
            }
            InitKeyBindings();
        }

        private void ContactButton_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Left)
            {
                IContact contact = ((Button)sender).DataContext as IContact;
                ((ViewModelGroupChat)this.DataContext).OpenPmCommand.Execute(contact);
            }
        }
        private void InitKeyBindings()
        {
            var locator = (ViewModelLocator)Application.Current.Resources["Locator"];
            KeyGestureConverter converter = new KeyGestureConverter();
            if (converter.IsValid((locator.CurrentClient.UserSettings.WinampKeyGesture)))
                this.WinampNowPlayingKeyBinding.Gesture = (KeyGesture)converter.ConvertFromString(locator.CurrentClient.UserSettings.WinampKeyGesture);
            if (converter.IsValid((locator.CurrentClient.UserSettings.SpotifyKeyGesture)))
                this.SpotifyNowPlayingKeyBinding.Gesture = (KeyGesture)converter.ConvertFromString(locator.CurrentClient.UserSettings.SpotifyKeyGesture);
        }

        private void GroupChatControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (DesignerProperties.GetIsInDesignMode(this))
                return;

            if (e.OldValue != null)
            {
                ViewModelChat vm = (ViewModelChat)e.OldValue;
                bool isAtEnd = ChatControl.AvalonConversation.TextArea.TextView.VerticalOffset + ChatControl.AvalonConversation.TextArea.TextView.ActualHeight + 5 >= ChatControl.AvalonConversation.TextArea.TextView.DocumentHeight;
                vm.IsScrolledToEnd = isAtEnd;
                vm.ScrollOffset = ChatControl.AvalonConversation.VerticalOffset;
                foreach (ImageElementGenerator gen in ((ViewModelChat)vm).ConversationElementGenerators.Union(((ViewModelChat)vm).MessageInputElementGenerators).Where(x => x is ImageElementGenerator))
                {
                    gen.CleanCache();
                }
                Window win = Window.GetWindow(this);
                if (win != null)
                {
                    win.Activated -= Window_Activated;
                    win.Deactivated -= Window_Deactivated;
                }
                Logger.Trace("Storing scroll offset: " + vm.ScrollOffset);
            }
            if (e.NewValue != null)
            {
                ViewModelGroupChat vm = (ViewModelGroupChat)e.NewValue;
                if (vm.ContactListState == ContactListState.Short)
                {
                    if (this.ContactList.Width == (double)Resources["ContactListWideWidth"])
                    {
                        Storyboard s = Resources["CollapseContactListWithoutAnim"] as Storyboard;
                        s.Begin();
                    }
                }
                else if (vm.ContactListState == ContactListState.Wide)
                {
                    if (this.ContactList.Width == (double)Resources["ContactListShortWidth"])
                    {
                        Storyboard s = Resources["ExpandContactListWithoutAnim"] as Storyboard;
                        s.Begin();
                    }
                }
                this.Dispatcher.BeginInvoke((Action)(() =>
                {
                    ChatControl.AvalonConversation.DoWhenLoaded(x => SetScroll());
                }), System.Windows.Threading.DispatcherPriority.Normal);

                CollectionViewSource source = (CollectionViewSource)this.Resources["GroupContactsViewSource"];
                source.View.Refresh();
            }
        }

        private void SetScroll()
        {
            ViewModelChat chatVm = (ViewModelChat)this.DataContext;
            if (chatVm.IsScrolledToEnd)
            {
                ChatControl.ForceScrollNextLineToEnd = true;
                ChatControl.SetScrollbar();
            }
            else
            {
                ChatControl.AvalonConversation.ScrollToVerticalOffset(chatVm.ScrollOffset);
                Logger.Trace("Tried to scroll to offset: " + chatVm.ScrollOffset);
            }
        }

        private void ChatControl_Loaded(object sender, RoutedEventArgs e)
        {
            if (DesignerProperties.GetIsInDesignMode(this))
                return;

            ChatControl.ScrollOffset = ((ViewModelGroupChat)this.DataContext).ScrollOffset;
            ChatControl.AvalonConversation.ScrollToVerticalOffset(ChatControl.ScrollOffset);

            ((ViewModelChat)this.DataContext).IsInputTextFocused = true;

            Window win = Window.GetWindow(this);
            if (win != null)
            {
                win.Activated += Window_Activated;
                win.Deactivated += Window_Deactivated;
            }
            Messenger.Default.Register<NotificationMessage>(this, msg =>
            {
                switch (msg.Notification)
                {
                    case "InitKeyBindings":
                        this.InitKeyBindings();
                        break;
                    case "ScrollDocument":
                        if (msg.Sender == this.DataContext)
                            this.ChatControl.SetScrollbar();
                        break;
                    case "ForceScrollDocument":
                        ChatControl.ForceScrollNextLineToEnd = true;
                        ChatControl.SetScrollbar();
                        break;
                    case "RedrawChatWindow":
                        this.ChatControl.AvalonConversation.TextArea.TextView.Redraw();
                        break;
                }
            });
        }

        private void CollectionViewSource_Filter(object sender, FilterEventArgs args)
        {
            if (this.DataContext == null)
                return;
            ViewModelGroupChat vm = (ViewModelGroupChat)this.DataContext;
            IContact model = (IContact)args.Item;
            if (model.ShowInContactList
                && model.ChatGroups.Any(x => x.ID == vm.ID)
                && ((model.ClientStatus != JmShared.ClientStatus.Offline) || Properties.Settings.Default.SettingShowOfflineContacts))
                args.Accepted = true;
            else
                args.Accepted = false;
        }

        private void ChatControl_Unloaded(object sender, RoutedEventArgs e)
        {
            Messenger.Default.Unregister(this);
            Logger.Debug("GroupChatcontrol unloaded");
        }

        private void Button_ToolTipOpening(object sender, ToolTipEventArgs e)
        {
            DependencyObject depObj = sender as DependencyObject;
            if (depObj == null) return;
            BindingExpression be = BindingOperations.GetBindingExpression(depObj, FrameworkElement.ToolTipProperty);
            if (be != null)
                be.UpdateTarget();
        }
        void Window_Deactivated(object sender, EventArgs e)
        {
            var vm = this.DataContext as ViewModelChat;
            if (vm != null)
                vm.IsFocused = false;

            this.ChatControl.AvalonConversation.TextArea.TextView.Redraw();
        }


        void Window_Activated(object sender, EventArgs e)
        {
            var vm = this.DataContext as ViewModelChat;
            if (vm != null)
                vm.IsFocused = true;

            this.ChatControl.AvalonConversation.TextArea.TextView.Redraw();
        }

        private void bnDownloadMessages_Click(object sender, RoutedEventArgs e)
        {
            ViewModelGroupChat vm = this.DataContext as ViewModelGroupChat;

            if (vm.IsDownloadMessagePopupOpen && this.bnDownloadMessages.IsChecked == false)
                vm.IsDownloadMessagePopupOpen = false;
            else if (!vm.IsDownloadMessagePopupOpen && this.bnDownloadMessages.IsChecked == true)
                vm.IsDownloadMessagePopupOpen = true;
        }
    }
}
